#include "ULGfx_History.h"

ULG_History ULG_History::historyData;

ULG_History *ULG_History::Instance()
{
	return &historyData;
}

int ULG_History::ShowSerial(SDL_Surface *destSurf, int serialNo)
{
	ULC_Serial *serial;
	int w, h;

	if (destSurf == NULL || (gfxFlags & ULG_HISTORY_F_FONT_SET) == 0 || (gfxFlags & ULG_HISTORY_F_ULG_SERIAL_SET) == 0){
		return -1;
	}

	serial = LookupSerial(serialNo);

	currentXY = startXY;

	if (serial == NULL){
		sprintf(msgBuffer, "Serial %-10d not found", serialNo);
		msg.SetText(msgBuffer);
		msg.Blit(destSurf, currentXY);
		return 0;
	}

	sprintf(msgBuffer, "Serial %-10d found:", serialNo);
	msg.SetText(msgBuffer);
	msg.Blit(destSurf, currentXY);
	msg.GetTextSize(&w, &h);

	currentXY.y += h;
	*ulgSerial = *serial;
	ulgSerial->SetXY(currentXY);

	return ulgSerial->Show(destSurf);
}

int ULG_History::ShowSerial(SDL_Surface *destSurf, const char *date)
{
	ULC_Serial *serial;
	int w, h;

	if (destSurf == NULL || (gfxFlags & ULG_HISTORY_F_FONT_SET) == 0 || (gfxFlags & ULG_HISTORY_F_ULG_SERIAL_SET) == 0){
		return -1;
	}

	serial = LookupSerial(date);

	currentXY = startXY;

	if (serial == NULL){
		sprintf(msgBuffer, "Serial at %s not found", date);
		msg.SetText(msgBuffer);
		msg.Blit(destSurf, currentXY);
		return 0;
	}

	sprintf(msgBuffer, "Serial %-10d found:", serial->sn);
	msg.SetText(msgBuffer);
	msg.Blit(destSurf, currentXY);
	msg.GetTextSize(&w, &h);

	currentXY.y += h;
	*ulgSerial = *serial;
	ulgSerial->SetXY(currentXY);

	return ulgSerial->Show(destSurf);
}

int ULG_History::ShowSerial(SDL_Surface *destSurf, ULC_Balls &balls)
{
	list<ULC_Serial *> retList;

	if (destSurf == NULL || (gfxFlags & ULG_HISTORY_F_FONT_SET) == 0 || (gfxFlags & ULG_HISTORY_F_ULG_SERIAL_SET) == 0){
		return -1;
	}
	
	currentXY = startXY;

	if ( LookupSerial(retList, balls) == -1){
		sprintf(msgBuffer, "Serial with %d %d %d %d %d %d %d not found", balls.reds[0], balls.reds[1], balls.reds[2], balls.reds[3], balls.reds[4], balls.reds[5], balls.blue);
		msg.SetText(msgBuffer);
		msg.Blit(destSurf, currentXY);
		return 0;
	}

	if (retList.size() != 0){
		*ulgSerial = *(retList.front());
		ulgSerial->SetXY(currentXY);
		ulgSerial->Show(destSurf);
	}

	return 0;
}

int ULG_History::ShowRange(SDL_Surface *destSurf, int startSerialNo, int count)
{
	ULC_Serial *serials;	
	int w, h;
	
	if (destSurf == NULL || (gfxFlags & ULG_HISTORY_F_FONT_SET) == 0 || (gfxFlags & ULG_HISTORY_F_ULG_SERIAL_SET) == 0 || count <= 0){
		return -1;
	}
	
	serials = LookupRange(startSerialNo, count);
	currentXY = startXY;

	if (serials == NULL){
		sprintf(msgBuffer, "Serial %-10d not found", startSerialNo);
		msg.SetText(msgBuffer);
		msg.Blit(destSurf, currentXY);
		return 0;
	}

	sprintf(msgBuffer, "%d serials start from %-10d(%s):", count, startSerialNo, serials[0].date);
	msg.SetText(msgBuffer);
	msg.Blit(destSurf, currentXY);
	msg.GetTextSize(&w, &h);
	
	currentXY.y += h;

	for (int i = 0; i < count; i++){
		sprintf(msgBuffer, "Serial %-10d(%s):", serials[i].sn, serials[i].date);
		msg.SetText(msgBuffer);
		msg.Blit(destSurf, currentXY);
		currentXY.y += h;
		*ulgSerial = serials[i];
		*ulgSerial->balls = ulgSerial->sortedBalls;
		ulgSerial->balls->SetFirstBallXY(currentXY);
		ulgSerial->balls->Show(destSurf);
		currentXY.y += ulgSerial->balls->GetRedBallImageHeight();
	}

	return 0;
}

int ULG_History::ShowRange(SDL_Surface *destSurf, const char *startDate, int count)
{
	ULC_Serial *serial;

	if (destSurf == NULL || (gfxFlags & ULG_HISTORY_F_FONT_SET) == 0 || (gfxFlags & ULG_HISTORY_F_ULG_SERIAL_SET) == 0 || count <= 0){
		return -1;
	}

	currentXY = startXY;
	serial = LookupSerial(startDate);

	if (serial == NULL){
		sprintf(msgBuffer, "Serial %-10d not found", serial->sn);
		msg.SetText(msgBuffer);
		msg.Blit(destSurf, currentXY);
		return 0;
	}

	return ShowRange(destSurf, serial->sn, count);
}

int ULG_History::ShowLatestNSerials(SDL_Surface *destSurf, int count)
{
	ULC_Serial *serials;

	if (destSurf == NULL || (gfxFlags & ULG_HISTORY_F_FONT_SET) == 0 || (gfxFlags & ULG_HISTORY_F_ULG_SERIAL_SET) == 0 || count <= 0){
		return -1;
	}

	serials = GetLatestSerials(count);

	currentXY = startXY;
	if (serials == NULL){
		sprintf(msgBuffer, "Getting latest serials failed");
		msg.SetText(msgBuffer);
		msg.Blit(destSurf, currentXY);
		return 0;
	}

	return ShowRange(destSurf, serials[0].sn, count);
}

int ULG_History::ShowLatestNSerialsWithBlueNumber(SDL_Surface *destSurf, int count, int blueNumber)
{
	list<ULC_Serial *> tmpList;
	list<ULC_Serial *>::iterator iter;
	int w, h;

	if (destSurf == NULL || (gfxFlags & ULG_HISTORY_F_FONT_SET) == 0 || (gfxFlags & ULG_HISTORY_F_ULG_SERIAL_SET) == 0 || count <= 0){
		return -1;
	}

	currentXY = startXY;

	if (GetLatestNSerialsWithBlueNumber(tmpList, count, blueNumber) == -1){
		sprintf(msgBuffer, "Getting latest serials with blue number %d failed", blueNumber);
		msg.SetText(msgBuffer);
		msg.Blit(destSurf, currentXY);
		return 0;
	}

	sprintf(msgBuffer, "Latest %d serials with blue number %d:", count, blueNumber);
	msg.SetText(msgBuffer);
	msg.Blit(destSurf, currentXY);
	msg.GetTextSize(&w, &h);

	currentXY.y += h;

	for (iter = tmpList.begin(); iter != tmpList.end(); iter++){
		sprintf(msgBuffer, "Serial %-10d(%s):", (*iter)->sn, (*iter)->date);
		msg.GetTextSize(&w, &h);
		msg.SetText(msgBuffer);
		msg.Blit(destSurf, currentXY);
		currentXY.y += h;
		*ulgSerial = *(*iter);
		*ulgSerial->balls = ulgSerial->sortedBalls;
		ulgSerial->balls->SetFirstBallXY(currentXY);
		ulgSerial->balls->Show(destSurf);
		currentXY.y += ulgSerial->balls->GetRedBallImageHeight();
	}

	return 0;
}

int ULG_History::SetFont(VSDL_Font *font)
{
	if (font == NULL){
		gfxFlags &= ~ULG_HISTORY_F_FONT_SET;
		return -1;
	}

	msg.SetFont(font);

	gfxFlags |= ULG_HISTORY_F_FONT_SET;
	return 0;
}

void ULG_History::SetStartXY(VSDL_Point point)
{
	startXY = point;
}

int ULG_History::SetULGSerial(ULG_Serial *serial)
{
	if (serial == NULL){
		gfxFlags &= ~ULG_HISTORY_F_ULG_SERIAL_SET;
		return -1;
	}

	ulgSerial = serial;
	gfxFlags |= ULG_HISTORY_F_ULG_SERIAL_SET;
	
	return 0;
}
